#ifndef TASK_EVENTLOOP_H
#define TASK_EVENTLOOP_H

#include <vector>
#include <memory>
#include <functional>

#include "copy/noncopyable.h"
#include "Thread.h"
#include "TimerId.h"
#include "Timestamp.h"
#include "Mutex.h"

class Poller;
class Channel;
class TimerQueue;


class EventLoop : muduo::noncopyable{
public:
    typedef std::function<void()> TimerCallback;
    typedef std::function<void()> Functor;

    EventLoop();
    ~EventLoop();

    void loop();

    void quit();

    bool isInLoopThread() const{
        return threadId_ == Thread::getTid();
    }

    void assertInLoopThread(){
        // if(!isInLoopThread()) abortNotInLoopThread();
        // 当发现当前事件循环不是在其对应的线程中, 就调用处理函数处理掉这个事件循环
    }

    static EventLoop * getEventLoopOfCurrentThread();

    /**
     * 从指定时间调用
     * @param time 指定调用时间
     * @param cb 回调事件
     * @return 返回标识id
     */
    TimerId runAt(Timestamp time, TimerCallback cb);

    /**
     * 在@c延迟秒后运行回调, 线程安全
     * @param delay 延迟时间
     * @param cb 调用事件
     * @return 返回对应时间时间标识id
     */
    TimerId runAfter(double delay, TimerCallback cb);

    /**
     * 每隔@c秒运行一次回调
     * 可以安全地从其他线程调用。
     * @param interval 间隔时间
     * @param cb 回调函数
     * @return 执行的时间时间的id
     */
    TimerId runEvery(double interval, TimerCallback cb);

    void wakeup();

    void updateChannel(Channel * channel);

    void runInLoop(const Functor & cb);

    void queueInLoop(const Functor & cb);



private:
    void abortNotInLoopThread();
    void handleRead();
    // 用于唤醒方法
    void doPendingFunctors();

    typedef std::vector<Channel *> ChannelList;

    bool looping_;
    // 标识现在是否有事件循环在执行
    bool quit_;
    bool callingPeningFunctors_;
    // 用于判断现在使用在IO线程中
    const pid_t threadId_;
    // 记录当前事件池所在线程
    Timestamp pollReturnTime_;
    std::shared_ptr<Poller> poller_;
    std::unique_ptr<TimerQueue> timerQueue_;
    int wakeupFd_;
    // 用于唤醒阻塞在poll的线程
    std::shared_ptr<Channel> wakeupChannel_;
    // 用于处理wakeupFd上的readable事件, 并将事件分发到handle-Read()函数中
    ChannelList activeChannels_;
    MutexLock mutex_;
    // 用于保护下面的pendingFunctors的,
    std::vector<Functor> pendingFunctors_;


};

#endif //TASK_EVENTLOOP_H
